/*
Flash controller for Arduino Uno Bord for S25FL128S flash 
*/
#include <SPI.h>
const int FCS = 36; //chip select pin


void setup() 
{
  Serial.begin(9600);// initialize serial communication at 9600 bits per second
  SPI.begin(); // initialize SPI:
  SPI.setBitOrder(MSBFIRST);//Sends all words in MSB to LSB order
  SPI.setClockDivider(SPI_CLOCK_DIV2); //sets SPI clock to 4MHz)
  pinMode(FCS, OUTPUT); //chip select pin - enable as output
  FlReset(); //reset flash
}

void FlProgram(byte adr, byte data) //funktion write to flash
{    
  FlWE(); //write enable command
  digitalWrite(FCS, LOW); //chip select is logic low
  SPI.transfer(0x02); // begin program commando
  SPI.transfer(adr);  //| first adress byte
  SPI.transfer(0x00); //| second adress byte
  SPI.transfer(0x00); //| third adress byte
  SPI.transfer(data); // send data
  digitalWrite(FCS,HIGH);//sets chip select to high 
  delay(10);
  FlWD(); // write disable command
}

byte FlRead ( byte adr) //funktion read from flash
{
  byte readed = 0;
  digitalWrite(FCS, LOW); //chip select is logic low
  SPI.transfer(0x03 ); //begin read command
  SPI.transfer(adr);  //| first adress byte
  SPI.transfer(0x00); //| second adress byte
  SPI.transfer(0x00); //| third adress byte
  readed =  SPI.transfer(0x00); // take input and load it to "readed"
  digitalWrite(FCS, HIGH); //chip select is logic high
  delay(10);
  return readed;
}

void FlErase (byte adr)
{
  FlWE();//write enable command    
  digitalWrite(FCS,LOW); //chip select is logic low
  SPI.transfer(0x20); //Sector erase command
  SPI.transfer(adr);  //| first adress byte
  SPI.transfer(0x00); //| second adress byte
  SPI.transfer(0x00); //| third adress byte
  digitalWrite(FCS,HIGH); //chip select is logic high
  delay(10);
  FlWD();//write disable command

}


//byte FlWriteStatReg(void) 
//{ 
//    
//  FlWE ();
//  digitalWrite(FCS,LOW); //chip select is logic low
//  SPI.transfer(0x01); //write registers command
//  SPI.transfer(0x00); //write 0x00 to status register
//  digitalWrite(FCS,HIGH); //chip select is logic high
//  delay(10);
//  FlWD ();
// 
//  
//  digitalWrite(FCS,LOW); //chip select is logic low
//  SPI.transfer(0x05); //read status register
//  byte readed = SPI.transfer(0x00); //dummy byte
//  digitalWrite(FCS,HIGH); //chip select is logic high
//  return readed;
//  
//
//
//
//}  

void FlWE (void)
{
  digitalWrite(FCS,LOW); //chip select is logic low
  SPI.transfer(0x06); // send write enable command
  digitalWrite(FCS, HIGH); //chip select is logic high
}

void FlWD (void)
{
  digitalWrite(FCS,LOW); //chip select is logic low
  SPI.transfer(0x04); //send write disable command
  digitalWrite(FCS,HIGH);//sets chip select to high

}
  
void FlReset (void)
{
  digitalWrite(FCS,LOW); //chip select is logic low
  SPI.transfer(0xF0); //send write disable command
  digitalWrite(FCS,HIGH);//sets chip select to high
  delay(10);
}



void loop () 
{
   byte data = 0x32; //data byte
   byte adr = 0x34;  //adress byte
   byte rd ;  //readed
 
//  rd= FlWriteStatReg();
//     Serial.print("status reg ");
//   Serial.println(rd,BIN); 
//   delay(10);
   
    FlErase(adr); //erase sector at adress (adr)
   rd = FlRead(adr);//read byte at adress adr
   Serial.print("deleted byte ");
   Serial.println(rd,HEX); 
   delay(1000);
   
   
    FlProgram(adr,data); // write data to adress (adr)
    rd = FlRead(adr);//read byte at adress adr
    Serial.print("programmed byte ");
    Serial.println(rd,HEX); 
   Serial.println(); 
   delay(1000);  

  

}

